package org.montecristo.posmobile.previo.camara;

import java.io.File;
import java.io.FileOutputStream;
import java.util.List;

import org.montecristo.posmobile.previo.MainActivity;
import org.montecristo.posmobile.previo.base.ManagerDB;
import org.montecristo.posmobile.previo.clases.Imagen;
import org.montecristo.posmobile.previo.clases.Tipo;
import org.montecristo.posmobile.previo.clases.encuesta.Applicacion;
import org.montecristo.posmobile.previo.servicio.Servico2UpdatePictures;
import org.montecristo.posmobile.previo.servicio.Sincronizar;




import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.ShutterCallback;
import android.hardware.Camera.Size;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
import android.widget.Button;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.TextView;
import android.widget.Toast;

import org.montecristo.posmobile.R;


public class CameraActivity extends Activity implements OnClickListener, OnTouchListener, Camera.AutoFocusCallback{

private Camera mCamera;
private CameraPreview mPreview;
LayoutInflater controlInflater = null;
Button cancel, captureI, captureN, OK, guardarButton;
EditText edit;
TextView tx;
Bitmap current_photo;
Applicacion applicacion_cliente;
int filecount;
ManagerDB manager;
boolean focusing = false, previewing = false;
DrawView dv;
long focus_start;

   @Override
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.camera_layout);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        
        getIntent();
        int idApp = Integer.parseInt(getIntent().getStringExtra("idApp"));
      
    manager = new ManagerDB(this);
    applicacion_cliente = manager.getApplicacionById(idApp+"");
        // Create an instance of Camera
        mCamera = getCameraInstance();
        Parameters mParameters = mCamera.getParameters();
        
        if( getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH) )
        mParameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);         
        
        android.hardware.Camera.Parameters parameters = mCamera.getParameters();
        List<String> focusModes = parameters.getSupportedFocusModes();
        if (focusModes.contains(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE))
        mParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);   
        mCamera.setParameters(mParameters);
        
        mPreview = new CameraPreview(this, mCamera);
        FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
        preview.addView(mPreview);
        
        controlInflater = LayoutInflater.from(getBaseContext());
        View viewControl = controlInflater.inflate(R.layout.controls, null);
        LayoutParams layoutParamsControl = new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT);
        this.addContentView(viewControl, layoutParamsControl);
        viewControl.setOnTouchListener(this);
        
        dv = new DrawView(this);
        dv.setLayoutParams(layoutParamsControl);
        preview.addView(dv);
        dv.bringToFront();
        
        cancel = (Button) findViewById(R.id.button_cancelar);
        cancel.getBackground().setAlpha(200);
        captureI = (Button) findViewById(R.id.button_capture);
        captureI.getBackground().setAlpha(200);
        captureN = (Button) findViewById(R.id.button_capture2);
        captureN.getBackground().setAlpha(200);
        guardarButton = (Button) findViewById(R.id.button_guardar);
        guardarButton.getBackground().setAlpha(200);
        OK = (Button) findViewById(R.id.button_ok);
        OK.getBackground().setAlpha(200);
        edit = (EditText) findViewById(R.id.editText1);
        tx = (TextView) findViewById(R.id.textview_cliente);
        
        
        if (Build.VERSION.SDK_INT > 11) {
        	android.app.ActionBar actionBar = getActionBar();
            actionBar.setDisplayShowTitleEnabled(true);
            actionBar.setTitle("| "+applicacion_cliente.toString()+" |");
            actionBar.setDisplayHomeAsUpEnabled(true);
            tx.setText("");
			
		}else{
			tx.setText(applicacion_cliente.toString());
			
		}
			
        
        
        
        OK.setOnClickListener(this);
        cancel.setOnClickListener(this);
        guardarButton.setOnClickListener(this);
        captureN.setOnClickListener(this);
        captureI.setOnClickListener(this);
        
        createDirIfNotExists("CapturasPrevios"+"/"+ applicacion_cliente.getCliente().getCarpetaImagenes()+"/");
        //>
        //>> busca en la carpeta si hay fotos ya guardadas para generar el nombre :/
        //>>> ej. previo0.jpg, previo1.jpg .... +
        filecount = 0;
        boolean found = false;
        try{
            File file;
            while(!found){
            file = new File(Environment.getExternalStorageDirectory()+"/CapturasPrevios"+"/"+ applicacion_cliente.getCliente().getCarpetaImagenes()+"/"+applicacion_cliente.getPrevio().getReferencia()+"-"+filecount+".jpg");
            if(!file.exists())
            	found=true;
            else
            	filecount++;
            }            
            }catch(Exception e){
            	Log.i("error_nombredearchivo", e.getMessage());
            }
    }
    
    public void onClick(View arg0) {
    	if(arg0.getId()==R.id.button_capture) {
    		captureI.setVisibility(View.GONE);
    		captureN.setVisibility(View.GONE);
    		cancel.setVisibility(View.VISIBLE);
    		OK.setVisibility(View.VISIBLE);
    		edit.setVisibility(View.VISIBLE);
    		previewing = true;
    		mCamera.takePicture(myShutterCallback,myPictureCallback_RAW, myPictureCallback_JPG);
    	}
    	if(arg0.getId()==R.id.button_capture2){
         guardarButton.setVisibility(View.VISIBLE);
         captureI.setVisibility(View.GONE);
         captureN.setVisibility(View.GONE);
         cancel.setVisibility(View.VISIBLE);
         previewing = true;
         mCamera.takePicture(myShutterCallback,myPictureCallback_RAW, myPictureCallback_JPG);
    	}
    	if(arg0.getId()==R.id.button_guardar){
    		guardarButton.setVisibility(View.GONE);
    		cancel.setVisibility(View.GONE);
    		captureI.setVisibility(View.VISIBLE);
    		captureN.setVisibility(View.VISIBLE);
    		try{
    			savePhoto(applicacion_cliente.getPrevio().getReferencia()+"-",false," ");
    			previewing=false;
    			mCamera.startPreview();
    			}catch(Exception e){
    				Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT);
    				Log.i("OK_button_reestartPreview ", e.getMessage());
    				}
    	}
    	if(arg0.getId()==R.id.button_cancelar){
    		guardarButton.setVisibility(View.GONE);
    		captureI.setVisibility(View.VISIBLE);
    		captureN.setVisibility(View.VISIBLE);
    		cancel.setVisibility(View.GONE);
    		OK.setVisibility(View.GONE);
    		edit.setVisibility(View.GONE);
    		try{
    			previewing=false;
    			mCamera.startPreview();
    			}catch(Exception e){
    				Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT);
    				Log.i("CANCEL_button_reestartPreview ", e.getMessage());}
    		}
    	if(arg0.getId()==R.id.button_ok){
    		try{
    			savePhoto(applicacion_cliente.getPrevio().getReferencia()+"-",true,edit.getText().toString());
    			edit.setText("");
    			previewing=false;
    			mCamera.startPreview();
    			}catch(Exception e){
    				Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT);
    				Log.i("OK_button_reestartPreview ", e.getMessage());}
    		captureI.setVisibility(View.VISIBLE);
    		captureN.setVisibility(View.VISIBLE);
    		cancel.setVisibility(View.GONE);
    		OK.setVisibility(View.GONE);
    		edit.setVisibility(View.GONE);
    		}
    	}
    ShutterCallback myShutterCallback = new ShutterCallback(){    
    	
    	public void onShutter() {   
     }};
    PictureCallback myPictureCallback_RAW = new PictureCallback(){

     public void onPictureTaken(byte[] arg0, Camera arg1) {
       
     }};
    PictureCallback myPictureCallback_JPG = new PictureCallback(){
    
    	public void onPictureTaken(byte[] arg0, Camera arg1) {
    		try {
    			Bitmap bitmapPicture = BitmapFactory.decodeByteArray(arg0, 0, arg0.length);
    			bitmapPicture = BitmapSizeHelper.createScaledBitmap(bitmapPicture, 800, 600, BitmapSizeHelper.ScalingLogic.CROP);
    			// bitmapPicture = Bitmap.createScaledBitmap(bitmapPicture, 800, 600, false);
    			current_photo = bitmapPicture;
    			} catch (Exception e) {
    				e.printStackTrace();
    				}
    		}
    };
   
    public void savePhoto(String fotoname,boolean incidencia,String comment){
    try{
    	Bitmap toSave = current_photo;
    	String filename = Environment.getExternalStorageDirectory().toString()+"/CapturasPrevios/"+applicacion_cliente.getCliente().getCarpetaImagenes()+"/"+fotoname+filecount+".jpg";
    	FileOutputStream out = new FileOutputStream(filename);
    	toSave.compress(Bitmap.CompressFormat.JPEG, 95, out);
    	if(!incidencia){
    		filename = Environment.getExternalStorageDirectory().toString()+"/CapturasPrevios/"+applicacion_cliente.getCliente().getCarpetaImagenes()+"/"+fotoname+filecount+"_thumb.jpg";
    		toSave = Bitmap.createScaledBitmap(toSave, 240, 180, false);
    		out = new FileOutputStream(filename);
    		toSave.compress(Bitmap.CompressFormat.JPEG, 95, out);}

    	// Toast.makeText(getApplicationContext(), "Guardada con éxito: "+fotoname+filecount+".jpg", Toast.LENGTH_LONG).show();

    	Imagen img = new Imagen();
    	img.setNombre(fotoname+filecount);
    	img.setAplicacion(applicacion_cliente);
    	img.setTipo(new Tipo());
    	if(incidencia){
    		img.getTipo().setIdTipo(1);
    		img.setUrl(Environment.getExternalStorageDirectory().toString()+"/CapturasPrevios/"+applicacion_cliente.getCliente().getCarpetaImagenes()+"/"+fotoname+filecount+".jpg");
    		img.setComentario(comment);
    	}
    	else{
    		img.setNombre(img.getNombre());
    		img.getTipo().setIdTipo(2);
    		img.setComentario(fotoname);
    		img.setUrl(Environment.getExternalStorageDirectory().toString()+"/CapturasPrevios/"+applicacion_cliente.getCliente().getCarpetaImagenes()+"/"+fotoname+filecount+"_thumb.jpg");
    	}
    	img.setEnviada((byte)0);
    	manager.insertImagen(img);
    	if(!incidencia){img.setNombre(fotoname+filecount);
    		img.getTipo().setIdTipo(3);
    		img.setUrl(Environment.getExternalStorageDirectory().toString()+"/CapturasPrevios/"+applicacion_cliente.getCliente().getCarpetaImagenes()+"/"+fotoname+filecount+".jpg");
    		manager.insertImagen(img);
    	}
    	filecount++;
    	startService(new Intent(CameraActivity.this,Servico2UpdatePictures.class));

    } catch (Exception e) {
    	e.printStackTrace();
    }
    }
    //@Override
    /*public boolean onCreateOptionsMenu(Menu menu) {
     //   getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }*/
    
    public static boolean createDirIfNotExists(String path) {
        boolean ret = true;
        try{
        File file = new File(Environment.getExternalStorageDirectory(), path);
        if (!file.exists()) {
            if (!file.mkdirs()) {
                Log.e("SaveImage :: ", "Problem creating Image folder");
                ret = false;
            }
        }
        }catch(Exception e){
        	Log.i("crear_carpeta_imagenes ", e.getMessage());
        }
        return ret;
    }
    public static Camera getCameraInstance(){
        Camera c = null;
        try {
            c = Camera.open(); // attempt to get a Camera instance
        }
        catch (Exception e){
        	Log.i("getCameraInstance", e.getMessage());             
        }
        return c; // returns null if camera is unavailable
    }
    private Camera.Size getBestPreviewSize(int width, int height,Camera.Parameters parameters) {   
    Camera.Size result=null;
    for (Camera.Size size : parameters.getSupportedPreviewSizes()) {   
    		if (size.width>=width && size.height>=height)
    			result=size;
    }
    	return(result);
    }    
    private Camera.Size getBestSize(int width, int height,Camera.Parameters parameters) {
        Camera.Size result=null;
        for (Camera.Size size : parameters.getSupportedPictureSizes()){
        	if (size.width>=width && size.height>=height)
        		result=size;
        }
       return(result);
    }
    /*public Bitmap getResizedBitmap(Bitmap bm, int newWidth,int newHeight) {﻿          ﻿  ﻿   
﻿  int width = bm.getWidth();﻿          ﻿  ﻿   
﻿  int height = bm.getHeight();﻿          ﻿  ﻿   
﻿  float scaleWidth = ((float) newWidth) / width;﻿          ﻿  ﻿   
﻿  float scaleHeight = ((float) newHeight) / height;﻿          ﻿  ﻿   
﻿  // CREATE A MATRIX FOR THE MANIPULATION﻿          ﻿  ﻿  ﻿          ﻿  ﻿   
﻿  Matrix matrix = new Matrix();﻿          ﻿  ﻿   
﻿  // RESIZE THE BIT MAP﻿          ﻿  ﻿   
﻿  matrix.postScale(scaleWidth, scaleHeight);﻿          ﻿  ﻿   
﻿  // RECREATE THE NEW BITMAP
﻿  Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false);﻿          ﻿  ﻿   
﻿  return resizedBitmap;}*/
   @Override
    public void startActivity(Intent intent) {
   
	   super.startActivity(intent);
	   overridePendingTransition(R.anim.animation_leave,
                R.anim.animation_enter);
    }
    
   @Override
    public void onBackPressed() {
        super.onBackPressed();        
        overridePendingTransition(R.anim.animation_leaver,R.anim.animation_enterr);
    }
   @Override
   public boolean onTouch(View arg0, MotionEvent arg1) {
	   if(!focusing&&!previewing){
		   focus_start = System.currentTimeMillis();
		   mCamera.autoFocus(this);
		   focusing = true;
		   dv.drawEnabled = true;
		   dv.invalidate();
	   }else if(focus_start!=-1){
		   if(System.currentTimeMillis()-focus_start>7000){
			   focusing=false; focus_start=-1; mCamera.cancelAutoFocus();}
	   }
	   return false;
   }

@Override
public void onAutoFocus(boolean success, Camera camera) {
	dv.drawEnabled = false;
	focusing = false;
	focus_start = -1;
	dv.invalidate();
	}

}

 class BitmapSizeHelper
{

    public static enum ScalingLogic
        {
            CROP, FIT
        }

    public static Bitmap getBitmapFromResources(Resources res, int resId, int dstWidth, int dstHeight, ScalingLogic scalingLogic)
        {
            Options options = new Options();
            options.inJustDecodeBounds = true;
            BitmapFactory.decodeResource(res, resId, options);
            options.inJustDecodeBounds = false;
            options.inSampleSize = calculateSampleSize(options.outWidth, options.outHeight, dstWidth, dstHeight, scalingLogic);
            Bitmap unscaledBitmap = BitmapFactory.decodeResource(res, resId, options);

            return unscaledBitmap;

        }

    public static Bitmap getBitmapFromPath(int targetW, int targetH, String photopath, int dstWidth, int dstHeight, ScalingLogic scalingLogic)
        {

            Options options = new Options();
            options.inJustDecodeBounds = true;
            BitmapFactory.decodeFile(photopath, options);
            options.inJustDecodeBounds = false;
            options.inSampleSize = calculateSampleSize(options.outWidth, options.outHeight, dstWidth, dstHeight, scalingLogic);
            Bitmap bitmap = BitmapFactory.decodeFile(photopath, options);

            return bitmap;

        }

    public static int calculateSampleSize(int srcWidth, int srcHeight, int dstWidth, int dstHeight, ScalingLogic scalingLogic)
        {
            if (scalingLogic == ScalingLogic.FIT)
                {
                    final float srcAspect = (float) srcWidth / (float) srcHeight;
                    final float dstAspect = (float) dstWidth / (float) dstHeight;

                    if (srcAspect > dstAspect)
                        {
                            return srcWidth / dstWidth;
                        }
                    else
                        {
                            return srcHeight / dstHeight;
                        }
                }
            else
                {
                    final float srcAspect = (float) srcWidth / (float) srcHeight;
                    final float dstAspect = (float) dstWidth / (float) dstHeight;

                    if (srcAspect > dstAspect)
                        {
                            return srcHeight / dstHeight;
                        }
                    else
                        {
                            return srcWidth / dstWidth;
                        }
                }
        }

    public static Bitmap createScaledBitmap(Bitmap unscaledBitmap, int dstWidth, int dstHeight, ScalingLogic scalingLogic)
        {
            Rect srcRect = calculateSrcRect(unscaledBitmap.getWidth(), unscaledBitmap.getHeight(), dstWidth, dstHeight, scalingLogic);
            Rect dstRect = calculateDstRect(unscaledBitmap.getWidth(), unscaledBitmap.getHeight(), dstWidth, dstHeight, scalingLogic);
            Bitmap scaledBitmap = Bitmap.createBitmap(dstRect.width(), dstRect.height(), Config.ARGB_8888);
            Canvas canvas = new Canvas(scaledBitmap);
            canvas.drawBitmap(unscaledBitmap, srcRect, dstRect, new Paint(Paint.FILTER_BITMAP_FLAG));

            return scaledBitmap;
        }

    public static Rect calculateSrcRect(int srcWidth, int srcHeight, int dstWidth, int dstHeight, ScalingLogic scalingLogic)
        {
            if (scalingLogic == ScalingLogic.CROP)
                {
                    final float srcAspect = (float) srcWidth / (float) srcHeight;
                    final float dstAspect = (float) dstWidth / (float) dstHeight;

                    if (srcAspect > dstAspect)
                        {
                            final int srcRectWidth = (int) (srcHeight * dstAspect);
                            final int srcRectLeft = (srcWidth - srcRectWidth) / 2;
                            return new Rect(srcRectLeft, 0, srcRectLeft + srcRectWidth, srcHeight);
                        }
                    else
                        {
                            final int srcRectHeight = (int) (srcWidth / dstAspect);
                            final int scrRectTop = (int) (srcHeight - srcRectHeight) / 2;
                            return new Rect(0, scrRectTop, srcWidth, scrRectTop + srcRectHeight);
                        }
                }
            else
                {
                    return new Rect(0, 0, srcWidth, srcHeight);
                }
        }

    public static Rect calculateDstRect(int srcWidth, int srcHeight, int dstWidth, int dstHeight, ScalingLogic scalingLogic)
        {
            if (scalingLogic == ScalingLogic.FIT)
                {
                    final float srcAspect = (float) srcWidth / (float) srcHeight;
                    final float dstAspect = (float) dstWidth / (float) dstHeight;

                    if (srcAspect > dstAspect)
                        {
                            return new Rect(0, 0, dstWidth, (int) (dstWidth / srcAspect));
                        }
                    else
                        {
                            return new Rect(0, 0, (int) (dstHeight * srcAspect), dstHeight);
                        }
                }
            else
                {
                    return new Rect(0, 0, dstWidth, dstHeight);
                }
        }

}